<h1>Lambda functions</h1>
<p>
    C++ and PHP both support lambda functions or anonymous functions (in 
    the C++ world the word 'lambda' is most used, PHP people speak about
    'anonymous functions'). With PHP-CPP you can pass these functions 
    from one language to the other. It is possible to call an anonymous 
    PHP function from your C++ code, and the other way around, to call a C++
    lambda from a PHP script.
</p>
<h2>Calling anonymous PHP functions from C++</h2>
<p>
    Let's start with a very simple example in PHP. In PHP you can create
    anonymous functions, and assign them to a variable (or pass them
    directly to a function).
</p>
<p>
<pre class="language-php"><code>&lt;?php
// anonymous PHP function stored in the variable $f
$f = function($a, $b) {
    
    // return the sum of the parameters
    return $a + $b;
};

// pass the function to another function
other_function($f);

// or pass an anonymous function without assigning it to a variable
other_function(function() {
    
    // return the product of the parameters
    return $a * $b;
});

?&gt;
</code></pre>
</p>
<p>
    The code above should be familiar to most PHP programmers. The 
    'other_function' can of course be implemented in PHP user space,
    but to demonstrate how to do this with PHP-CPP we are going to
    build it with C++. Just like all the other functions that you've
    seen in the earlier examples, such a C++ function function receives 
    a Php::Parmeters object as its parameter, which is a std::vector of 
    Php::Value objects.
</p>
<p>
<pre class="language-c++"><code>#include &lt;phpcpp.h&gt;
/**
 *  Native function that is callable from PHP
 *
 *  This function gets one parameter that holds a callable anonynous
 *  PHP function.
 *
 *  @param  params      The parameters passed to the function
 */
void other_function(Php::Parameters &amp;params)
{
    // make sure the function was really called with at least one parameter
    if (params.size() == 0) return;

    // this function is called from PHP user space, and it is called
    // with a anonymous function as its first parameter
    Php::Value func = params[0];
    
    // the Php::Value class has implemented the operator (), which allows
    // us to use the object just as if it is a real function
    Php::Value result = func(3, 4);
    
    // @todo do something with the result
}

/**
 *  Switch to C context, because the Zend engine expects the get_module()
 *  to have a C style function signature
 */
extern "C" {
    /**
     *  Startup function that is automatically called by the Zend engine
     *  when PHP starts, and that should return the extension details
     *  @return void*
     */
    PHPCPP_EXPORT void *get_module() 
    {
        // the extension object
        static Php::Extension extension("my_extension", "1.0");
        
        // add the example function so that it can be called from PHP scripts
        extension.add("other_function", other_function);
        
        // return the extension details
        return extension;
    }
}</code></pre>
</p>
<p>
    It is that simple. But the other way around is possible too. Imagine
    we have a function in PHP user space code that accepts a callback 
    function. The following function is a simple version of the 
    PHP array_map() function:
</p>
<p>
<pre class="language-php"><code>&lt;?php
// function that iterates over an array, and calls a function on every
// element in that array, it returns a new array with every item
// replaced by the result of the callback
function my_array_map($array, $callback) {
    
    // initial result variable
    $result = array();
    
    // loop through the array
    foreach ($array as $index => $item) {
        
        // call the callback on the item
        $result[$index] = $callback($item);
    }
    
    // done
    return $result;
}
?&gt;
</code></pre>
</p>
<p>
    Imagine that we want to call this PHP function from your C++ code,
    using a C++ lambda function as a callback. This is possible, and easy:
</p>
<p>
<pre class="language-c++"><code>#include &lt;phpcpp.h&gt;
/**
 *  Native function that is callable from PHP
 */
void run_test()
{
    // create the anonymous function
    Php::Function multiply_by_two([](Php::Parameters &amp;params) -> Php::Value {
        
        // make sure the function was really called with at least one parameter
        if (params.size() == 0) return nullptr;
        
        // one parameter is passed to the function
        Php::Value param = params[0];
        
        // multiple the parameter by two
        return param * 2;
    });

    // the function now is callable
    Php::Value four = multiply_by_two(2);
    
    // a Php::Function object is a derived Php::Value, and its value can 
    // also be stored in a normal Php::Value object, it will then still 
    // be a callback function then
    Php::Value value = multiply_by_two;
    
    // the value object now also holds the function
    Php::Value six = value(3);
    
    // create an array
    Php::Value array;
    array[0] = 1;
    array[1] = 2;
    array[2] = 3;
    array[3] = 4;
    
    // call the user-space function
    Php::Value result = Php::call("my_array_map", array, multiply_by_two);
    
    // @todo do something with the result variable (which now holds
    // an array with values 2, 4, 6 and 8).
}

/**
 *  Switch to C context, because the Zend engine expects the get_module()
 *  to have a C style function signature
 */
extern "C" {
    /**
     *  Startup function that is automatically called by the Zend engine
     *  when PHP starts, and that should return the extension details
     *  @return void*
     */
    PHPCPP_EXPORT void *get_module() 
    {
        // the extension object
        static Php::Extension extension("my_extension", "1.0");
        
        // add the example function so that it can be called from PHP scripts
        extension.add("run_test", run_test);
        
        // return the extension details
        return extension;
    }
}</code></pre>
</p>
<p>
    In the example we assigned a C++ lambda function to a Php::Function
    object. The Php::Function class is derived from the Php::Value class.
    The only difference between a Php::Value and a Php::Function is
    that the constructor of Php::Function accepts a function. Despite 
    that difference, both classes are completely identical. In fact, we 
    would have preferred to make it possible to assign C++ functions 
    directly to Php::Value objects, and skip the Php::Function 
    constructor, but that is impossible because of calling ambiguities.
</p>
<p>
    The Php::Function class can be used as if it is a normal Php::Value
    object: you can assign it to other Php::Value objects, and you
    can use it as a parameter when you call user space PHP functions.
    In the above example we do exactly that: we call the user space
    my_array_map() function with our own 'multiply_by_two' C++ function.
</p>
<h2>Signature of the C++ function</h2>
<p>
    You can pass different sort of C++ functions to the Php::Function
    constructor, as long as they are compatible with the following two
    function signatures:
</p>
<p>
<pre class="language-c++"><code>
Php::Value function();
Php::Value function(Php::Parameters &amp;params);
</code></pre>
</p>
<p>
    Internally, the Php::Function class uses a C++ std::function object 
    to store the function, so anything that can be stored in such a 
    std::function object, can be assigned to the Php::Function class.
</p>
